package driver;

import io.ConstantReader;

import java.util.Random;

import nodes.typeconst.ConstantStrategy;
import nodes.typeconst.DoubleConstantState;
import nodes.typeconst.DoubleIntegerConstantStrategy;
import nodes.typeconst.PIConstantStrategy;

import evol.Evolver;
import evol.FirstNodeOutputter;
import evol.OutputterComposite;
import evol.TreeOutputter;
import evol.XMLOutputter;
import func.FunctionFactory;
import func.FunctionFactoryImpl;
import func.equ.Equation;
import func.equ.MafEquation;
import func.rank.EquRankFunction;
import func.rank.RankFunction;

public class Main {

	public static void main(String[] args) {
		Equation<Double> equ = new MafEquation();
		ConstantReader read = new ConstantReader("out.txt", 200);
		Double[][] data = read.getConstantArray();
		if(data == null) {
			System.out.println("Data array is null");
			return;
		}
		
		RankFunction<Double> rank = new EquRankFunction(data, equ);
		FunctionFactory<Double> func = new 
			FunctionFactoryImpl<Double>("miscdouble+basicdouble+basetrigometricdouble");
		ConstantStrategy<Double> strat = new DoubleConstantState(
				new DoubleIntegerConstantStrategy(), new PIConstantStrategy());
		//TreeOutputter out = new FirstNodeOutputter();
		//TreeOutputter out = new XMLOutputter("xml");
		TreeOutputter out = new OutputterComposite(new FirstNodeOutputter(),
				new XMLOutputter("xml"));
		Evolver<Double> evolution = new Evolver<Double>(rank, func, strat, out);
		evolution.evolve();
		
//		RankFunction<Integer> rank = new PolyRankFunction(buildSet());
//		//FunctionFactory<Integer> func = new BasicIntegerFuncs();
//		FunctionFactory<Integer> func = new FunctionFactoryImpl<Integer>("basicinteger");
//		ConstantStrategy<Integer> strat = new IntegerConstantStrategy();
//		Evolver<Integer> evolution = new Evolver<Integer>(rank, func, strat);
//		evolution.evolve();
	}
	
	public static int func(int x, int y) {
		return x*x + 3*x + 2*y + 5;
		//return x*x+y*y+2*x;
	}
	
	public static Integer[][] buildSet() {
		Integer[][] data = new Integer[200][3];
		Random ran = new Random();
		for(int i = 0; i < 200; i++) {
			int x = ran.nextInt(40);
			int y = ran.nextInt(40);
			data[i][0] = x; data[i][1] = y;
			data[i][2] = func(x, y);
		}
		
		return data;
	}
}
